<template>
  <div class="adhoc-execution-container">
    <!-- 星空背景 -->
    <div class="starry-background">
      <div class="stars"></div>
      <div class="stars2"></div>
      <div class="stars3"></div>
    </div>

    <!-- 主要内容区域 -->
    <div class="adhoc-content">
      <!-- 页面头部 -->
      <div class="page-header glass-effect">
        <div class="header-content">
          <div class="title-section">
            <h1 class="page-title">
              <i class="fa fa-bolt"></i>
              Ad-hoc执行
            </h1>
            <p class="page-subtitle">快速执行Ansible命令，实时查看执行结果</p>
          </div>
        </div>
      </div>

    <!-- 快速执行区域 -->
    <div class="execution-form-section">
      <div class="section-header">
        <h3>⚡ 快速执行</h3>
        <div class="header-actions">
          <el-button
            size="large"
            @click="executeAdhoc"
            :loading="executing"
            :disabled="!commandContent.trim() || !selectedInventory || !selectedAnsibleConfig"
            class="glass-button primary execute-button"
          >
            <i class="fa fa-rocket"></i>
            {{ executing ? '执行中...' : '立即执行' }}
          </el-button>

          <!-- 取消按钮 -->
          <el-button
            v-if="executing"
            size="large"
            @click="cancelExecution"
            :loading="cancelling"
            class="glass-button danger cancel-button"
          >
            <i class="fa fa-stop"></i>
            {{ cancelling ? '取消中...' : '取消执行' }}
          </el-button>

          <el-button
            size="large"
            @click="validateCommand"
            :loading="validating"
            :disabled="executing"
            class="glass-button validate-button"
          >
            <i class="fa fa-check-circle"></i>
            验证命令
          </el-button>

        </div>
      </div>

      <!-- Ansible配置、主机清单和凭据选择 -->
      <div class="inventory-selection">
        <el-form-item label="选择Ansible配置" class="config-form-item">
          <el-select
            v-model="selectedAnsibleConfig"
            @change="onAnsibleConfigChange"
            placeholder="请选择Ansible配置"
            class="glass-select"
            style="width: 300px"
            :loading="loadingConfigs"
          >
            <el-option
              v-for="config in ansibleConfigs"
              :key="config.id"
              :label="config.name"
              :value="config.id"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="选择主机清单" class="inventory-form-item">
          <el-select
            v-model="selectedInventory"
            placeholder="请选择主机清单"
            class="glass-select"
            style="width: 300px"
            :loading="loadingInventories"
            :disabled="!selectedAnsibleConfig"
          >
            <el-option
              v-for="inventory in inventories"
              :key="inventory.id"
              :label="inventory.name"
              :value="inventory.id"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="选择凭据" class="credential-form-item">
          <el-select
            v-model="selectedCredential"
            placeholder="请选择认证凭据（可选）"
            class="glass-select"
            style="width: 300px"
            :loading="loadingCredentials"
            clearable
          >
            <el-option
              v-for="credential in credentials"
              :key="credential.id"
              :label="`${credential.name} (${credential.credential_type_display})`"
              :value="credential.id"
            >
              <div class="credential-option">
                <span class="credential-name">{{ credential.name }}</span>
                <el-tag
                  :type="getCredentialTypeColor(credential.credential_type)"
                  size="small"
                  class="credential-type-tag"
                >
                  {{ credential.credential_type_display }}
                </el-tag>
              </div>
            </el-option>
          </el-select>
        </el-form-item>
      </div>

      <!-- Monaco编辑器 -->
      <div class="command-editor">
        <div ref="monacoEditor" class="monaco-container"></div>
      </div>
    </div>

    <!-- 实时终端 -->
    <div class="terminal-section">
      <div class="terminal-header">
        <h3>💻 执行终端</h3>
        <div class="terminal-actions">
          <el-button @click="clearTerminal" size="small" class="action-glass-button clear-action">
            <i class="fa fa-eraser"></i>
            清空
          </el-button>
          <el-button @click="scrollTerminalToBottom" size="small" class="action-glass-button scroll-action">
            <i class="fa fa-arrow-down"></i>
            滚动到底部
          </el-button>
        </div>
      </div>

      <div ref="terminalContainer" class="terminal-container">
        <div v-if="terminalLines.length === 0" class="terminal-placeholder">
          <i class="fa fa-terminal"></i>
          <p>等待命令执行...</p>
          <p class="terminal-tip">在上方编辑器中输入ansible命令，然后点击"立即执行"</p>
        </div>

        <div v-else class="terminal-content">
          <div
            v-for="line in terminalLines"
            :key="line.id"
            class="terminal-line"
            :class="`terminal-${line.type}`"
          >
            <span class="terminal-timestamp">[{{ line.timestamp }}]</span>
            <span
              v-if="line.type === 'job-link'"
              class="terminal-text terminal-link"
              @click="viewJobDetail(line.jobId)"
            >
              {{ line.text }}
            </span>
            <span v-else class="terminal-text">{{ line.text }}</span>
          </div>
        </div>
      </div>
    </div>

    <!-- 主机模式帮助对话框 -->
    <el-dialog v-model="showPatternHelp" title="主机模式帮助" width="600px">
      <div class="pattern-help">
        <h4>常用主机模式:</h4>
        <ul>
          <li><code>all</code> - 所有主机</li>
          <li><code>web*</code> - 以web开头的主机</li>
          <li><code>db[1:5]</code> - db1到db5的主机</li>
          <li><code>192.168.1.*</code> - 特定IP段的主机</li>
          <li><code>webservers:dbservers</code> - 多个组的并集</li>
          <li><code>webservers:!dbservers</code> - 排除特定组</li>
        </ul>
      </div>
    </el-dialog>

    <!-- 模块帮助对话框 -->
    <el-dialog v-model="showModuleHelp" title="模块文档" width="800px">
      <div v-if="selectedModuleDoc" class="module-help">
        <h4>{{ selectedModuleDoc.name }}</h4>
        <p>{{ selectedModuleDoc.short_description }}</p>
        <div v-if="selectedModuleDoc.parameters" class="module-parameters">
          <h5>参数列表:</h5>
          <el-table :data="selectedModuleDoc.parameters" style="width: 100%">
            <el-table-column prop="name" label="参数名" width="120" />
            <el-table-column prop="description" label="描述" />
            <el-table-column prop="required" label="必需" width="60">
              <template #default="scope">
                <el-tag v-if="scope.row.required" type="danger" size="small">是</el-tag>
                <el-tag v-else type="info" size="small">否</el-tag>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
      <div v-else class="no-module-selected">
        <p>请先选择一个模块</p>
      </div>
    </el-dialog>

    </div> <!-- 闭合 adhoc-content -->
  </div> <!-- 闭合 adhoc-execution-container -->
</template>

<script setup lang="ts">
import { ElMessage } from 'element-plus'
import * as monaco from 'monaco-editor'
import { computed, nextTick, onBeforeUnmount, onMounted, reactive, ref, watch } from 'vue'
import { ansibleAPI } from '@/api/ansible'
import { useAppStore } from '@/stores'
import { getAuthToken, isAuthenticated } from '@/utils/cache'
import { registerAnsibleCommandLanguage, unregisterAnsibleCommandLanguage, setCurrentInventoryId, getDefaultAnsibleCommand } from '@/utils/ansible-command-language.js'

// 导入Monaco编辑器语言支持
import 'monaco-editor/esm/vs/basic-languages/shell/shell.contribution'
import 'monaco-editor/esm/vs/editor/editor.api'



// 响应式数据
const executing = ref(false)
const validating = ref(false)
const cancelling = ref(false)
const loadingConfigs = ref(false)
const loadingInventories = ref(false)
const loadingCredentials = ref(false)
const ansibleConfigs = ref([])
const inventories = ref([])
const credentials = ref([])
const selectedAnsibleConfig = ref(null)
const selectedInventory = ref(null)
const selectedCredential = ref(null)
const modules = ref([])
const parameterSuggestions = ref([])
const currentExecution = ref(null)
const executionHistory = ref([])
const showPatternHelp = ref(false)
const showModuleHelp = ref(false)
const selectedModuleDoc = ref(null)

// 获取store和认证状态
const store = useAppStore()
const authStatus = ref({
  isAuthenticated: false,
  token: '',
  userInfo: null
})

// Monaco编辑器相关
const monacoEditor = ref(null)
const terminalContainer = ref(null)
let editorInstance = null
const commandContent = ref('')
const terminalOutput = ref('')
const terminalLines = ref([])
const isTerminalScrolledToBottom = ref(true)

// 表单数据
const formData = reactive({
  inventory_id: null,
  pattern: 'all',
  module_name: '',
  module_args: '',
  extra_vars: '',
  check_mode: false,
  diff_mode: false,
  verbose: false
})

// 默认命令模板已移至 ansible-command-language.js

// 表单验证规则
const formRules = {
  inventory_id: [
    { required: true, message: '请选择Inventory', trigger: 'change' }
  ],
  pattern: [
    { required: true, message: '请输入主机模式', trigger: 'blur' }
  ],
  module_name: [
    { required: true, message: '请选择Ansible模块', trigger: 'blur' }
  ]
}

// 计算属性
const canExecute = computed(() => {
  return commandContent.value.trim() && !executing.value
})

// 方法
const loadAnsibleConfigs = async () => {
  loadingConfigs.value = true
  try {
    const response = await ansibleAPI.getConfigs()
    ansibleConfigs.value = response.data.results || response.data || []
    console.log('加载Ansible配置成功:', ansibleConfigs.value.length)
  } catch (error) {
    console.error('加载Ansible配置失败:', error)
    ElMessage.error('加载Ansible配置失败: ' + (error.response?.data?.message || error.message))
    ansibleConfigs.value = []
  } finally {
    loadingConfigs.value = false
  }
}

const loadInventories = async (configId?: number) => {
  if (!configId && !selectedAnsibleConfig.value) {
    inventories.value = []
    selectedInventory.value = null
    return
  }

  const targetConfigId = configId || selectedAnsibleConfig.value

  loadingInventories.value = true
  try {
    const response = await ansibleAPI.getInventories({ config_id: targetConfigId })
    inventories.value = response.data.results || response.data || []
    console.log('加载主机清单成功:', inventories.value.length)

    // 清空之前的选择
    selectedInventory.value = null

    // 如果没有数据，显示提示
    if (inventories.value.length === 0) {
      ElMessage.warning('该Ansible配置下暂无可用的主机清单，请先创建')
    }
  } catch (error) {
    console.error('加载主机清单失败:', error)
    if (error.response?.status === 404) {
      ElMessage.warning('Ansible Inventory API暂未实现，请联系管理员')
    } else {
      ElMessage.error('加载主机清单失败: ' + (error.response?.data?.message || error.message))
    }
    inventories.value = []
  } finally {
    loadingInventories.value = false
  }
}

// 当Ansible配置改变时的处理函数
const onAnsibleConfigChange = async (configId: number) => {
  console.log('Ansible配置改变:', configId)

  // 加载对应配置下的inventory
  await loadInventories(configId)
}

// 加载凭据列表
const loadCredentials = async () => {
  loadingCredentials.value = true
  try {
    const response = await ansibleAPI.getCredentials({ is_active: true })

    // 处理不同的响应格式
    if (response.data.results) {
      credentials.value = response.data.results
    } else if (Array.isArray(response.data)) {
      credentials.value = response.data
    } else {
      credentials.value = response.data.data?.results || response.data.data || []
    }

    console.log('加载凭据成功:', credentials.value.length)
  } catch (error) {
    console.error('加载凭据失败:', error)
    ElMessage.error('加载凭据失败: ' + (error.response?.data?.message || error.message))
  } finally {
    loadingCredentials.value = false
  }
}

// 获取凭据类型颜色
const getCredentialTypeColor = (type) => {
  const colors = {
    ssh_key: 'primary',
    password: 'success',
    aws_key: 'warning',
    vault: 'info'
  }
  return colors[type] || 'info'
}

const clearForm = () => {
  const defaultCommand = getDefaultAnsibleCommand()
  if (editorInstance) {
    editorInstance.setValue(defaultCommand)
  }
  commandContent.value = defaultCommand
}



const validateCommand = () => {
  if (!commandContent.value.trim()) {
    ElMessage.error('请输入要验证的命令')
    return
  }

  validating.value = true
  addTerminalLine('正在验证命令语法...', 'output')

  setTimeout(() => {
    // 简单的命令验证逻辑
    const command = commandContent.value.trim()
    if (command.startsWith('ansible')) {
      addTerminalLine('✅ 命令语法验证通过', 'success')
      ElMessage.success('命令验证通过')
    } else {
      addTerminalLine('❌ 命令格式错误，请确保以"ansible"开头', 'error')
      ElMessage.error('命令格式错误')
    }
    validating.value = false
  }, 1000)
}

const executeAdhoc = async () => {
  if (!commandContent.value.trim()) {
    ElMessage.error('请输入要执行的命令')
    return
  }

  if (!selectedAnsibleConfig.value) {
    ElMessage.error('请选择Ansible配置')
    return
  }

  if (!selectedInventory.value) {
    ElMessage.error('请选择主机清单')
    return
  }

  executing.value = true

  try {
    // 清空终端
    clearTerminal()

    // 显示执行的命令
    addTerminalLine(`$ ${commandContent.value}`, 'command')
    addTerminalLine('正在执行命令...', 'output')

    // 调用真实的Ad-hoc执行API
    try {
      const requestData = {
        inventory_id: selectedInventory.value,
        command: commandContent.value.trim()
      }

      // 如果选择了凭据，添加到请求中
      if (selectedCredential.value) {
        requestData.credential_id = selectedCredential.value
        const selectedCred = credentials.value.find(c => c.id === selectedCredential.value)
        if (selectedCred) {
          addTerminalLine(`🔐 使用凭据: ${selectedCred.name} (${selectedCred.credential_type_display})`, 'output')
        }
      }

      const response = await ansibleAPI.runAdhoc(requestData)

      const data = response.data.data

      // 设置当前执行
      currentExecution.value = {
        id: data.job_id,
        status: data.status,
        start_time: new Date().toISOString(),
        command: commandContent.value,
        output: ''
      }

      ElMessage.success('Ad-hoc命令已启动')
      addTerminalLine(`✅ 任务已启动，Job ID: ${data.job_id}`, 'success')
      addTerminalLine(`📋 模块: ${data.module_name}`, 'output')
      addTerminalLine(`🎯 目标: ${data.pattern}`, 'output')
      addTerminalLine(`🔗 点击查看详情: Job #${data.job_id}`, 'job-link', data.job_id)
      addTerminalLine('', 'output')

      // 开始监控执行状态
      monitorExecution(data.job_id)

    } catch (error) {
      console.error('执行Ad-hoc命令失败:', error)
      const errorMsg = error.response?.data?.message || error.message
      addTerminalLine(`❌ 执行失败: ${errorMsg}`, 'error')
      ElMessage.error('执行失败: ' + errorMsg)
      executing.value = false  // 只有在启动失败时才设置为false
    }

  } catch (error) {
    console.error('执行Ad-hoc命令失败:', error)
    addTerminalLine(`错误: ${error.message}`, 'error')
    ElMessage.error('执行失败: ' + error.message)
    executing.value = false  // 只有在启动失败时才设置为false
  }
}

// 取消执行
const cancelExecution = async () => {
  if (!currentExecution.value) {
    ElMessage.warning('没有正在执行的任务')
    return
  }

  cancelling.value = true
  try {
    const response = await ansibleAPI.cancelJob(currentExecution.value.id)

    if (response.data.status === 'success') {
      ElMessage.success('任务已取消')
      addTerminalLine('⚠️ 任务已被用户取消', 'output')

      // 更新当前执行状态
      if (currentExecution.value) {
        currentExecution.value.status = 'cancelled'
      }

      // 停止监控
      executing.value = false
    } else {
      ElMessage.error('取消任务失败: ' + (response.data.message || '未知错误'))
    }
  } catch (error) {
    console.error('取消任务失败:', error)
    ElMessage.error('取消任务失败: ' + (error.response?.data?.message || error.message))

    // 强制停止前端状态
    addTerminalLine('⚠️ 强制停止任务监控', 'output')
    executing.value = false
    if (currentExecution.value) {
      currentExecution.value.status = 'cancelled'
    }
  } finally {
    cancelling.value = false
  }
}

// 解析主机执行结果，参考AWX格式
const parseHostResult = (line, status) => {
  // 解析主机名
  const hostMatch = line.match(/^([^\s|]+)\s*\|/)
  const hostname = hostMatch ? hostMatch[1].trim() : 'unknown'

  // 状态图标和颜色
  const statusConfig = {
    'SUCCESS': { icon: '✅', color: 'success', label: 'SUCCESS' },
    'CHANGED': { icon: '🔄', color: 'changed', label: 'CHANGED' },
    'FAILED': { icon: '❌', color: 'error', label: 'FAILED' },
    'UNREACHABLE': { icon: '🚫', color: 'warning', label: 'UNREACHABLE' }
  }

  const config = statusConfig[status] || statusConfig['SUCCESS']

  // 显示主机状态行，增强视觉效果
  addTerminalLine('', 'output')
  addTerminalLine(`┌─ ${config.icon} ${hostname} | ${config.label} ─────────────────────`, config.color)

  // 解析详细输出
  if (line.includes('| rc=')) {
    // 格式: devops01 | CHANGED | rc=0 | (stdout) ...
    const parts = line.split('|')
    let stdout = '', stderr = '', rc = ''

    parts.forEach(part => {
      const trimmed = part.trim()
      if (trimmed.startsWith('rc=')) {
        rc = trimmed.substring(3)
      } else if (trimmed.startsWith('(stdout)')) {
        stdout = trimmed.substring(8).trim()
      } else if (trimmed.startsWith('(stderr)')) {
        stderr = trimmed.substring(8).trim()
      }
    })

    // 显示返回码
    if (rc) {
      addTerminalLine(`   📊 Return Code: ${rc}`, rc === '0' ? 'success' : 'error')
    }

    // 显示标准输出，根据状态添加不同颜色
    if (stdout) {
      addTerminalLine(`   📄 Output:`, 'output')
      // 格式化多行输出，根据状态使用不同颜色
      const outputColorType = status === 'SUCCESS' ? 'success-output' :
                             status === 'CHANGED' ? 'changed-output' :
                             status === 'FAILED' ? 'error-output' : 'output'

      stdout.split('\\n').forEach(outputLine => {
        if (outputLine.trim()) {
          // 特殊处理常见命令的输出格式
          const formattedLine = formatCommandOutput(outputLine, status)
          addTerminalLine(`      ${formattedLine}`, outputColorType)
        }
      })
    }

    // 显示错误输出
    if (stderr) {
      addTerminalLine(`   ⚠️ Error:`, 'error')
      stderr.split('\\n').forEach(errorLine => {
        if (errorLine.trim()) {
          addTerminalLine(`      ${errorLine}`, 'error')
        }
      })
    }
  } else if (line.includes('=>')) {
    // JSON格式输出: devops01 | SUCCESS => {"changed": false, "ping": "pong"}
    const jsonPart = line.split('=>')[1]?.trim()
    if (jsonPart) {
      try {
        const jsonResult = JSON.parse(jsonPart)
        addTerminalLine(`   📄 Result:`, 'output')

        // 格式化JSON显示，根据状态使用不同颜色
        const jsonColorType = status === 'SUCCESS' ? 'success-json' :
                             status === 'CHANGED' ? 'changed-json' :
                             status === 'FAILED' ? 'error-json' : 'json'

        Object.entries(jsonResult).forEach(([key, value]) => {
          const valueStr = typeof value === 'object' ? JSON.stringify(value) : String(value)
          // 为不同类型的值添加特殊格式
          const formattedValue = formatJsonValue(key, valueStr, status)
          addTerminalLine(`      ${key}: ${formattedValue}`, jsonColorType)
        })
      } catch {
        addTerminalLine(`   📄 Raw: ${jsonPart}`, 'output')
      }
    }
  }

  // 添加结束分隔线
  addTerminalLine(`└─────────────────────────────────────────────`, config.color)
  addTerminalLine('', 'output')
}

// 格式化命令输出，添加语法高亮
const formatCommandOutput = (line, status) => {
  // 去掉转义字符
  let cleanLine = line.replace(/\\n/g, '\n').replace(/\\t/g, '\t')

  // 根据内容类型进行特殊格式化

  // 1. 文件系统信息 (df -h)
  if (cleanLine.match(/^\s*\/dev\/|^\s*tmpfs|^\s*Filesystem/)) {
    return `🗂️  ${cleanLine}`
  }

  // 2. 进程信息 (ps, top)
  if (cleanLine.match(/^\s*PID|^\s*\d+\s+\w+/)) {
    return `⚙️  ${cleanLine}`
  }

  // 3. 网络信息 (netstat, ss)
  if (cleanLine.match(/tcp|udp|LISTEN|ESTABLISHED/i)) {
    return `🌐 ${cleanLine}`
  }

  // 4. 系统负载 (uptime, w)
  if (cleanLine.match(/load average|up \d+/i)) {
    return `📊 ${cleanLine}`
  }

  // 5. 内存信息 (free)
  if (cleanLine.match(/Mem:|Swap:|total|used|free|available/i)) {
    return `💾 ${cleanLine}`
  }

  // 6. 用户信息 (who, w)
  if (cleanLine.match(/pts\/|tty\d+/)) {
    return `👤 ${cleanLine}`
  }

  // 7. 日期时间
  if (cleanLine.match(/\d{4}-\d{2}-\d{2}|\w{3}\s+\d{1,2}\s+\d{2}:\d{2}/)) {
    return `🕐 ${cleanLine}`
  }

  // 8. 文件权限 (ls -l)
  if (cleanLine.match(/^[drwx-]{10}/)) {
    return `📁 ${cleanLine}`
  }

  // 9. 错误信息
  if (cleanLine.match(/error|failed|denied|not found/i)) {
    return `❌ ${cleanLine}`
  }

  // 10. 成功信息
  if (cleanLine.match(/success|ok|done|complete/i)) {
    return `✅ ${cleanLine}`
  }

  // 默认返回原始内容
  return cleanLine
}

// 格式化JSON值，添加语义化图标
const formatJsonValue = (key, value, status) => {
  // 根据键名添加相应图标
  switch (key.toLowerCase()) {
    case 'changed':
      return value === 'true' ? '🔄 true' : '⚪ false'
    case 'failed':
      return value === 'true' ? '❌ true' : '✅ false'
    case 'ping':
      return value === 'pong' ? '🏓 pong' : `🏓 ${value}`
    case 'rc':
    case 'return_code':
      return value === '0' ? '✅ 0' : `❌ ${value}`
    case 'stdout':
      return `📄 ${value}`
    case 'stderr':
      return `⚠️ ${value}`
    case 'msg':
    case 'message':
      return `💬 ${value}`
    case 'ansible_facts':
      return `📋 ${value}`
    case 'invocation':
      return `⚙️ ${value}`
    default:
      return value
  }
}

// 格式化Ansible错误信息
const formatAnsibleError = (errorLine) => {
  // 常见的Ansible错误模式
  if (errorLine.includes('UNREACHABLE')) {
    return `🚫 ${errorLine}`
  } else if (errorLine.includes('FAILED')) {
    return `❌ ${errorLine}`
  } else if (errorLine.includes('Permission denied')) {
    return `🔒 权限被拒绝: ${errorLine}`
  } else if (errorLine.includes('Connection refused')) {
    return `🔌 连接被拒绝: ${errorLine}`
  } else if (errorLine.includes('No route to host')) {
    return `🌐 网络不可达: ${errorLine}`
  } else if (errorLine.includes('Host key verification failed')) {
    return `🔑 主机密钥验证失败: ${errorLine}`
  } else if (errorLine.includes('Authentication failed')) {
    return `🔐 认证失败: ${errorLine}`
  } else if (errorLine.includes('Timeout')) {
    return `⏰ 连接超时: ${errorLine}`
  } else if (errorLine.includes('Name or service not known')) {
    return `🔍 主机名解析失败: ${errorLine}`
  } else if (errorLine.includes('SSH Error')) {
    return `🔧 SSH错误: ${errorLine}`
  } else {
    return errorLine
  }
}

// 终端输出管理
const addTerminalLine = (text, type = 'output', jobId = null) => {
  const timestamp = new Date().toLocaleTimeString()
  terminalLines.value.push({
    id: Date.now() + Math.random(),
    timestamp,
    text,
    type, // 'output', 'error', 'command', 'success', 'job-link'
    jobId // 任务ID，用于点击查看详情
  })

  // 自动滚动到底部
  if (isTerminalScrolledToBottom.value) {
    nextTick(() => {
      scrollTerminalToBottom()
    })
  }
}

const scrollTerminalToBottom = () => {
  if (terminalContainer.value) {
    terminalContainer.value.scrollTop = terminalContainer.value.scrollHeight
  }
}

const clearTerminal = () => {
  terminalLines.value = []
  terminalOutput.value = ''
}

// 查看任务详情
const viewJobDetail = (jobId) => {
  if (!jobId) return

  // 打开新窗口查看任务详情
  const detailUrl = `/ansible/jobs/${jobId}/detail`
  window.open(detailUrl, '_blank')
}

const monitorExecution = async (jobId) => {
  let attempts = 0
  const maxAttempts = 60 // 最多检查60次，每次间隔2秒，总共2分钟

  const checkStatus = async () => {
    try {
      const response = await ansibleAPI.getJobStatus(jobId)
      const jobData = response.data.data || response.data

      // 检查jobData是否存在
      if (!jobData) {
        console.error('获取任务状态失败: 响应数据为空')
        executing.value = false
        return
      }

      // 更新当前执行状态
      if (currentExecution.value) {
        currentExecution.value.status = jobData.status
      }

      if (jobData.status === 'running') {
        addTerminalLine('⏳ 任务正在执行中...', 'output')

        // 如果还在运行且未超过最大尝试次数，继续检查
        attempts++
        if (attempts < maxAttempts) {
          setTimeout(checkStatus, 2000) // 2秒后再次检查
        } else {
          addTerminalLine('⚠️ 任务执行超时，停止监控', 'output')
        }
      } else if (jobData.status === 'success') {
        // 任务成功完成
        addTerminalLine('', 'output')
        addTerminalLine('🎉 ===== 执行成功 =====', 'success')
        addTerminalLine('', 'output')

        if (jobData.stdout) {
          // 解析并格式化Ansible输出，参考AWX风格
          const outputLines = jobData.stdout.split('\n')

          outputLines.forEach(line => {
            if (line.trim()) {
              // 解析不同类型的输出
              if (line.includes('| SUCCESS =>') || line.includes('| SUCCESS |')) {
                parseHostResult(line, 'SUCCESS')
              } else if (line.includes('| CHANGED |') || line.includes('| CHANGED =>')) {
                parseHostResult(line, 'CHANGED')
              } else if (line.includes('| FAILED =>') || line.includes('| FAILED |')) {
                parseHostResult(line, 'FAILED')
              } else if (line.includes('| UNREACHABLE =>') || line.includes('| UNREACHABLE |')) {
                parseHostResult(line, 'UNREACHABLE')
              } else {
                // 其他输出直接显示
                addTerminalLine(line, 'output')
              }
            }
          })
        }

        addTerminalLine('', 'output')
        addTerminalLine('✅ 任务执行完成', 'success')

        // 添加到历史记录
        executionHistory.value.unshift({
          id: jobId,
          ...currentExecution.value,
          end_time: new Date().toISOString()
        })

        // 任务完成，停止执行状态
        executing.value = false

      } else if (jobData.status === 'failed') {
        // 任务失败
        addTerminalLine('', 'output')
        addTerminalLine('💥 ===== 执行失败 =====', 'error')
        addTerminalLine('', 'output')

        // 显示详细错误信息
        if (jobData.stderr && jobData.stderr.trim()) {
          addTerminalLine('🔍 错误详情:', 'error')
          const errorLines = jobData.stderr.split('\n')
          errorLines.forEach(line => {
            if (line.trim()) {
              // 解析常见的Ansible错误
              const formattedError = formatAnsibleError(line)
              addTerminalLine(`   ${formattedError}`, 'error')
            }
          })
          addTerminalLine('', 'output')
        }

        // 显示错误分析和建议
        if (jobData.result && jobData.result.error_analysis) {
          const analysis = jobData.result.error_analysis
          addTerminalLine('🔧 错误分析:', 'warning')
          addTerminalLine(`   类型: ${analysis.error_type}`, 'warning')
          addTerminalLine(`   描述: ${analysis.description}`, 'warning')

          if (analysis.suggestions && analysis.suggestions.length > 0) {
            addTerminalLine('', 'output')
            addTerminalLine('💡 解决建议:', 'info')
            analysis.suggestions.forEach((suggestion, index) => {
              addTerminalLine(`   ${index + 1}. ${suggestion}`, 'info')
            })
          }
          addTerminalLine('', 'output')
        }

        // 如果有stdout输出，也显示出来（可能包含部分成功的主机）
        if (jobData.stdout && jobData.stdout.trim()) {
          addTerminalLine('📄 执行输出:', 'output')
          const outputLines = jobData.stdout.split('\n')

          outputLines.forEach(line => {
            if (line.trim()) {
              // 解析不同类型的输出
              if (line.includes('| SUCCESS =>') || line.includes('| SUCCESS |')) {
                parseHostResult(line, 'SUCCESS')
              } else if (line.includes('| CHANGED |') || line.includes('| CHANGED =>')) {
                parseHostResult(line, 'CHANGED')
              } else if (line.includes('| FAILED =>') || line.includes('| FAILED |')) {
                parseHostResult(line, 'FAILED')
              } else if (line.includes('| UNREACHABLE =>') || line.includes('| UNREACHABLE |')) {
                parseHostResult(line, 'UNREACHABLE')
              } else if (line.includes('| UNREACHABLE!')) {
                // 处理UNREACHABLE!格式: web01 | UNREACHABLE!: Failed to connect...
                const parts = line.split('| UNREACHABLE!')
                const host = parts[0].trim()
                const error = parts[1] ? parts[1].trim() : ''

                addTerminalLine('', 'output')
                addTerminalLine(`┌─ 🚫 ${host} | UNREACHABLE ─────────────────────`, 'warning')
                if (error) {
                  addTerminalLine(`│  ⚠️ Error: ${error}`, 'error')
                }
                addTerminalLine(`└─────────────────────────────────────────────`, 'warning')
                addTerminalLine('', 'output')
              } else {
                // 其他错误信息
                addTerminalLine(`   ${line}`, 'error')
              }
            }
          })
          addTerminalLine('', 'output')
        }

        // 不显示详细统计信息，保持简洁

        // 如果没有具体错误信息，显示通用错误
        if ((!jobData.stderr || !jobData.stderr.trim()) && (!jobData.stdout || !jobData.stdout.trim())) {
          addTerminalLine('⚠️ 未获取到详细错误信息', 'error')
          addTerminalLine('可能的原因:', 'error')
          addTerminalLine('   • 目标主机网络不可达', 'error')
          addTerminalLine('   • SSH连接被拒绝', 'error')
          addTerminalLine('   • 认证失败', 'error')
          addTerminalLine('   • 防火墙阻止连接', 'error')
        }

        // 任务失败，停止执行状态
        executing.value = false

      } else if (jobData.status === 'cancelled') {
        addTerminalLine('⚠️ 任务已被取消', 'output')
        // 任务取消，停止执行状态
        executing.value = false
      }

    } catch (error) {
      console.error('获取任务状态失败:', error)
      addTerminalLine(`❌ 获取任务状态失败: ${error.message}`, 'error')
    }
  }

  // 开始检查状态
  checkStatus()
}

// Monaco编辑器初始化
const initMonacoEditor = async () => {
  if (!monacoEditor.value) return

  try {
    // 注册Ansible命令语言
    registerAnsibleCommandLanguage()

    // 创建编辑器实例
    editorInstance = monaco.editor.create(monacoEditor.value, {
      value: commandContent.value || getDefaultAnsibleCommand(),
      language: 'ansible-command',
      theme: 'ansible-command-dark',
      fontSize: 14,
      lineNumbers: 'on',
      roundedSelection: false,
      scrollBeyondLastLine: false,
      readOnly: false,
      automaticLayout: true,
      minimap: { enabled: false },
      wordWrap: 'on',
      lineHeight: 20,
      padding: { top: 10, bottom: 10 },
      // 智能提示配置 - 只在用户主动触发时显示
      quickSuggestions: {
        other: true,
        comments: false,
        strings: true
      },
      quickSuggestionsDelay: 300,
      suggestOnTriggerCharacters: true,  // 允许特定字符触发
      acceptSuggestionOnCommitCharacter: true,
      acceptSuggestionOnEnter: 'on',
      tabCompletion: 'on',
      wordBasedSuggestions: true,
      // 智能提示配置 - 恢复正常功能
      suggest: {
        insertMode: 'insert',
        filterGraceful: true,
        localityBonus: true,
        showKeywords: true,
        showSnippets: true,
        showFunctions: true,
        showVariables: true,
        showModules: true,
        showClasses: true,
        showColors: true,
        showFiles: true,
        showReferences: true,
        showFolders: true,
        showTypeParameters: true,
        showIssues: true,
        showUsers: true,
        showValues: true,
        showWords: true,
        showStatusBar: true,
        showIcons: true,
        maxVisibleSuggestions: 6,
        // 控制提示框位置 - 从下往上弹出
        suggestWidgetPosition: 'above'
      }
    })

    // 监听内容变化
    editorInstance.onDidChangeModelContent(() => {
      commandContent.value = editorInstance.getValue()
    })

    // 智能提示应该自动触发，不需要快捷键

    // 添加快捷键支持 - Ctrl+Space 触发智能提示
    editorInstance.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Space, () => {
      editorInstance.trigger('keyboard', 'editor.action.triggerSuggest', {})
    })

    // 基本的智能提示支持
    console.log('Monaco编辑器初始化完成，智能提示已启用')

    // 设置当前inventory ID以支持智能提示
    if (selectedInventory.value) {
      setCurrentInventoryId(selectedInventory.value)
    }

    console.log('Monaco编辑器初始化成功，已启用Ansible智能提示')
  } catch (error) {
    console.error('Monaco编辑器初始化失败:', error)
  }
}

// 监听inventory变化，更新智能提示
watch(selectedInventory, (newInventoryId) => {
  if (newInventoryId) {
    setCurrentInventoryId(newInventoryId)
    console.log('更新智能提示的inventory ID:', newInventoryId)
  }
})

// 生命周期
onMounted(() => {
  console.log('Ad-hoc执行页面已加载')

  // 设置默认命令
  commandContent.value = getDefaultAnsibleCommand()

  loadAnsibleConfigs()  // 先加载Ansible配置
  loadCredentials()  // 加载凭据列表

  // 初始化Monaco编辑器
  nextTick(() => {
    initMonacoEditor()
  })
})

onBeforeUnmount(() => {
  console.log('Ad-hoc页面正在卸载，开始清理资源')

  // 清理Monaco编辑器
  if (editorInstance) {
    try {
      editorInstance.dispose()
      console.log('Monaco编辑器已清理')
    } catch (error) {
      console.error('清理Monaco编辑器时出错:', error)
    } finally {
      editorInstance = null
    }
  }

  // 清理Ansible Command语言注册
  unregisterAnsibleCommandLanguage()

  // 清理其他资源
  terminalLines.value = []
  currentExecution.value = null

  // 强制垃圾回收（如果可能）
  if (window.gc) {
    window.gc()
  }

  console.log('Ad-hoc页面清理完成')
})

// 监听inventory选择变化，更新智能提示上下文
watch(selectedInventory, (newInventoryId) => {
  if (newInventoryId) {
    setCurrentInventoryId(newInventoryId)
    console.log('设置当前inventory ID:', newInventoryId)
  }
}, { immediate: true })
</script>

<style lang="scss" scoped>
/* 主容器 */
.adhoc-execution-container {
  position: relative;
  min-height: calc(100vh - 60px);
  background: linear-gradient(135deg,
    rgba(0, 0, 0, 0.9) 0%,
    rgba(20, 20, 40, 0.95) 50%,
    rgba(0, 0, 0, 0.9) 100%
  );
  overflow-x: hidden;
  padding-bottom: 80px; /* 为footer留出空间 */
}

/* 星空背景 */
.starry-background {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

.stars, .stars2, .stars3 {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: transparent;
}

.stars {
  background-image:
    radial-gradient(2px 2px at 20px 30px, #eee, transparent),
    radial-gradient(2px 2px at 40px 70px, rgba(255,255,255,0.8), transparent),
    radial-gradient(1px 1px at 90px 40px, #fff, transparent);
  background-repeat: repeat;
  background-size: 200px 100px;
  animation: zoom 20s infinite linear;
}

.stars2 {
  background-image:
    radial-gradient(1px 1px at 40px 60px, #fff, transparent),
    radial-gradient(1px 1px at 120px 10px, rgba(255,255,255,0.7), transparent);
  background-repeat: repeat;
  background-size: 300px 200px;
  animation: zoom 40s infinite linear;
}

.stars3 {
  background-image:
    radial-gradient(1px 1px at 10px 10px, rgba(255,255,255,0.5), transparent);
  background-repeat: repeat;
  background-size: 400px 300px;
  animation: zoom 60s infinite linear;
}

@keyframes zoom {
  from { transform: scale(1); }
  to { transform: scale(1.5); }
}

/* 主要内容区域 */
.adhoc-content {
  position: relative;
  z-index: 10;
  padding: 20px;
  max-width: 1400px;
  margin: 0 auto;
}

/* 玻璃效果基础样式 */
.glass-effect {
  background: rgba(164, 244, 186, 0.1);
  border: 1px solid rgba(164, 244, 186, 0.2);
  border-radius: 12px;
  backdrop-filter: blur(20px);
  box-shadow:
    0 8px 32px rgba(0, 0, 0, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

/* 页面标题区域 */
.page-header {
  margin-bottom: 20px;
  padding: 20px;
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 30px;
}

.title-section {
  flex: 1;
}

.page-title {
  color: #00eaff;
  font-size: 2em;
  margin: 0 0 8px 0;
  text-shadow: 0 0 20px rgba(0, 234, 255, 0.5);
  display: flex;
  align-items: center;
  gap: 12px;

  i {
    font-size: 0.8em;
  }
}

.page-subtitle {
  color: rgba(255, 255, 255, 0.7);
  font-size: 1.1em;
  margin: 0;
}

.header-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

/* 玻璃按钮样式 */
.glass-action-btn {
  background: rgba(164, 244, 186, 0.1) !important;
  border: 1px solid rgba(164, 244, 186, 0.3) !important;
  color: rgba(255, 255, 255, 0.9) !important;
  backdrop-filter: blur(10px) !important;
  border-radius: 6px !important;
  padding: 8px 12px !important;
  font-size: 12px !important;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
  display: flex !important;
  align-items: center !important;
  gap: 4px !important;
  min-width: 80px !important;
  justify-content: center !important;
  box-shadow:
    0 2px 8px rgba(0, 0, 0, 0.1),
    inset 0 1px 0 rgba(255, 255, 255, 0.1) !important;

  i {
    font-size: 12px !important;
  }

  span {
    font-size: 12px !important;
  }

  &:hover {
    background: rgba(164, 244, 186, 0.2) !important;
    border-color: rgba(164, 244, 186, 0.5) !important;
    color: #00eaff !important;
    transform: translateY(-1px) !important;
    box-shadow:
      0 4px 12px rgba(0, 0, 0, 0.2),
      inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
  }

  &:active {
    transform: translateY(0) !important;
  }
}

/* 快速执行区域 */
.execution-form-section {
  background: rgba(164, 244, 186, 0.1);
  border: 1px solid rgba(164, 244, 186, 0.2);
  border-radius: 12px;
  backdrop-filter: blur(20px);
  box-shadow:
    0 8px 32px rgba(0, 0, 0, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
  padding: 20px;
  margin-bottom: 20px;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.section-header h3 {
  margin: 0;
  color: #00eaff;
  font-size: 1.5em;
  text-shadow: 0 0 10px rgba(0, 234, 255, 0.3);
}

/* 主机清单选择区域 */
.inventory-selection {
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
}

.config-form-item,
.inventory-form-item,
.credential-form-item {
  margin-bottom: 0;
  background: transparent !important;

  :deep(.el-form-item__label) {
    color: rgba(255, 255, 255, 0.9);
    font-weight: 500;
    margin-bottom: 8px;
  }

  :deep(.el-form-item__content) {
    line-height: normal;
    background: transparent !important;
  }

  /* 移除深蓝色背景 */
  :deep(.el-form-item) {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
  }

  /* 移除asterisk样式 */
  :deep(.el-form-item.asterisk-left) {
    background: transparent !important;
    border: none !important;
  }
}

.glass-select {
  :deep(.el-input__wrapper) {
    background: rgba(164, 244, 186, 0.1) !important;
    border: 1px solid rgba(164, 244, 186, 0.3) !important;
    backdrop-filter: blur(10px) !important;
    border-radius: 8px !important;
    box-shadow:
      0 2px 8px rgba(0, 0, 0, 0.1),
      inset 0 1px 0 rgba(255, 255, 255, 0.1) !important;
  }

  :deep(.el-input__inner) {
    color: rgba(255, 255, 255, 0.9) !important;
    background: transparent !important;

    &::placeholder {
      color: rgba(255, 255, 255, 0.5) !important;
    }
  }

  :deep(.el-input__wrapper:hover) {
    border-color: rgba(164, 244, 186, 0.5) !important;
  }

  :deep(.el-input__wrapper.is-focus) {
    border-color: #00eaff !important;
    box-shadow:
      0 4px 12px rgba(0, 0, 0, 0.2),
      inset 0 1px 0 rgba(255, 255, 255, 0.2),
      0 0 10px rgba(0, 234, 255, 0.3) !important;
  }
}

/* 下拉菜单样式 */
:deep(.el-select-dropdown) {
  background: rgba(0, 0, 0, 0.8) !important;
  border: 1px solid rgba(164, 244, 186, 0.3) !important;
  backdrop-filter: blur(20px) !important;
  border-radius: 8px !important;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5) !important;
  z-index: 9999999 !important;
}

:deep(.el-select-dropdown__item) {
  color: rgba(255, 255, 255, 0.9) !important;
  background: transparent !important;
}

:deep(.el-select-dropdown__item:hover) {
  background: rgba(164, 244, 186, 0.2) !important;
  color: #ffffff !important;
}

:deep(.el-select-dropdown__item.selected) {
  background: rgba(0, 234, 255, 0.3) !important;
  color: #ffffff !important;
}

/* Monaco编辑器 */
.command-editor {
  background: rgba(0, 0, 0, 0.4);
  border-radius: 12px;
  overflow: visible;
  border: 1px solid rgba(164, 244, 186, 0.3);
  box-shadow:
    0 4px 16px rgba(0, 0, 0, 0.2),
    inset 0 1px 0 rgba(255, 255, 255, 0.05);
}

.monaco-container {
  height: 60px;
  width: 100%;
  border-radius: 12px;
}

/* 实时终端 */
.terminal-section {
  background: rgba(164, 244, 186, 0.1);
  border: 1px solid rgba(164, 244, 186, 0.2);
  border-radius: 12px;
  backdrop-filter: blur(20px);
  box-shadow:
    0 8px 32px rgba(0, 0, 0, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
  padding: 30px;
  margin-top: 30px;
  position: relative;
  z-index: 1;
}

.terminal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.terminal-header h3 {
  margin: 0;
  color: #00eaff;
  font-size: 1.5em;
  text-shadow: 0 0 10px rgba(0, 234, 255, 0.3);
}

.terminal-actions {
  display: flex;
  gap: 10px;
}

/* 强制覆盖全局样式 */
.terminal-section .terminal-container {
  background-color: #000000 !important;
  border-radius: 12px;
  border: 1px solid rgba(164, 244, 186, 0.3);
  height: 500px;
  overflow-y: auto;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.8);
}

.terminal-container {
  background-color: #000000 !important;
  border-radius: 12px;
  border: 1px solid rgba(164, 244, 186, 0.3);
  height: 500px;
  overflow-y: auto;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.8);
  padding: 20px;
  font-family: 'Courier New', 'Monaco', 'Menlo', monospace;
  font-size: 13px;
  line-height: 1.5;
  box-shadow:
    0 4px 16px rgba(0, 0, 0, 0.2),
    inset 0 1px 0 rgba(255, 255, 255, 0.05);

  /* 隐藏滚动条但保持功能 */
  scrollbar-width: none;
  -ms-overflow-style: none;

  &::-webkit-scrollbar {
    display: none;
  }
}

.terminal-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: rgba(255, 255, 255, 0.5);
  text-align: center;
}

.terminal-placeholder i {
  font-size: 48px;
  margin-bottom: 15px;
  color: rgba(164, 244, 186, 0.4);
  text-shadow: 0 0 10px rgba(164, 244, 186, 0.2);
}

.terminal-placeholder p {
  margin: 5px 0;
  color: rgba(255, 255, 255, 0.6);
}

.terminal-tip {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.4) !important;
}

.terminal-content {
  height: 100%;
  background: #000000;
  padding: 15px;
  border-radius: 8px;
}

.terminal-line {
  margin-bottom: 3px;
  word-wrap: break-word;
  white-space: pre-wrap;
  transition: all 0.2s ease;
}

.terminal-timestamp {
  color: rgba(164, 244, 186, 0.6);
  font-size: 11px;
  margin-right: 10px;
  text-shadow: 0 0 5px rgba(164, 244, 186, 0.2);
}

.terminal-text {
  color: rgba(255, 255, 255, 0.8);
}

/* 终端不同类型的输出样式 */
.terminal-command .terminal-text {
  color: #00eaff;
  font-weight: bold;
  text-shadow: 0 0 5px rgba(0, 234, 255, 0.3);
}

.terminal-error .terminal-text {
  color: #ff6b6b;
  text-shadow: 0 0 5px rgba(255, 107, 107, 0.3);
}

.terminal-success .terminal-text {
  color: #51cf66;
  text-shadow: 0 0 5px rgba(81, 207, 102, 0.3);
}

.terminal-output .terminal-text {
  color: rgba(255, 255, 255, 0.8);
}

/* Ansible状态颜色高亮 - 提高优先级 */
.terminal-container .terminal-content .terminal-changed .terminal-text {
  color: #ffa726 !important;
  text-shadow: 0 0 5px rgba(255, 167, 38, 0.3) !important;
  font-weight: bold !important;
}

.terminal-container .terminal-content .terminal-warning .terminal-text {
  color: #ffeb3b !important;
  text-shadow: 0 0 5px rgba(255, 235, 59, 0.3) !important;
  font-weight: bold !important;
}

/* JSON高亮样式 - 提高优先级 */
.terminal-container .terminal-content .terminal-json .terminal-text {
  color: #4fc3f7 !important;
  text-shadow: 0 0 5px rgba(79, 195, 247, 0.3) !important;
  font-family: 'Courier New', monospace !important;
  background: rgba(79, 195, 247, 0.1) !important;
  padding: 2px 4px !important;
  border-radius: 3px !important;
}

.terminal-container .terminal-content .terminal-success-json .terminal-text {
  color: #81c784 !important;
  text-shadow: 0 0 5px rgba(129, 199, 132, 0.3) !important;
  font-family: 'Courier New', monospace !important;
  background: rgba(129, 199, 132, 0.1) !important;
  padding: 2px 4px !important;
  border-radius: 3px !important;
}

.terminal-container .terminal-content .terminal-error-json .terminal-text {
  color: #ff8a80 !important;
  text-shadow: 0 0 5px rgba(255, 138, 128, 0.3) !important;
  font-family: 'Courier New', monospace !important;
  background: rgba(255, 138, 128, 0.1) !important;
  padding: 2px 4px !important;
  border-radius: 3px !important;
}

.terminal-container .terminal-content .terminal-warning-json .terminal-text {
  color: #fff176 !important;
  text-shadow: 0 0 5px rgba(255, 241, 118, 0.3) !important;
  font-family: 'Courier New', monospace !important;
  background: rgba(255, 241, 118, 0.1) !important;
  padding: 2px 4px !important;
  border-radius: 3px !important;
}

.terminal-container .terminal-content .terminal-changed-json .terminal-text {
  color: #ffcc80 !important;
  text-shadow: 0 0 5px rgba(255, 204, 128, 0.3) !important;
  font-family: 'Courier New', monospace !important;
  background: rgba(255, 204, 128, 0.1) !important;
  padding: 2px 4px !important;
  border-radius: 3px !important;
}

/* 可点击的任务链接 */
.terminal-link {
  color: #00eaff !important;
  cursor: pointer !important;
  text-decoration: underline !important;
  transition: all 0.3s ease !important;
}

.terminal-link:hover {
  color: #ffffff !important;
  text-shadow: 0 0 10px rgba(0, 234, 255, 0.5) !important;
  background: rgba(0, 234, 255, 0.1) !important;
  padding: 2px 4px !important;
  border-radius: 3px !important;
}

/* 命令输出内容高亮 */
.terminal-container .terminal-content .terminal-success-output .terminal-text {
  color: #a8e6cf !important;
  text-shadow: 0 0 3px rgba(168, 230, 207, 0.3) !important;
  font-family: 'Courier New', monospace !important;
}

.terminal-container .terminal-content .terminal-changed-output .terminal-text {
  color: #ffd93d !important;
  text-shadow: 0 0 3px rgba(255, 217, 61, 0.3) !important;
  font-family: 'Courier New', monospace !important;
}

.terminal-container .terminal-content .terminal-error-output .terminal-text {
  color: #ffb3ba !important;
  text-shadow: 0 0 3px rgba(255, 179, 186, 0.3) !important;
  font-family: 'Courier New', monospace !important;
}

.terminal-container .terminal-content .terminal-warning-output .terminal-text {
  color: #ffffba !important;
  text-shadow: 0 0 3px rgba(255, 255, 186, 0.3) !important;
  font-family: 'Courier New', monospace !important;
}

/* Monaco编辑器智能提示样式 - 已移至底部统一处理 */

:deep(.monaco-editor .suggest-widget .monaco-list .monaco-list-row) {
  background: transparent !important;
  color: rgba(255, 255, 255, 0.9) !important;
}

:deep(.monaco-editor .suggest-widget .monaco-list .monaco-list-row.focused) {
  background: rgba(164, 244, 186, 0.2) !important;
  color: #ffffff !important;
}

:deep(.monaco-editor .suggest-widget .monaco-list .monaco-list-row .monaco-icon-label .monaco-icon-label-container .monaco-icon-name-container .label-name) {
  color: inherit !important;
}

:deep(.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon) {
  opacity: 0.8;
}

/* 确保Monaco编辑器容器有足够的z-index */
.monaco-editor-container {
  position: relative;
  z-index: 1;
  min-height: 200px;
  margin-bottom: 20px;
}

:deep(.monaco-editor) {
  position: relative;
  z-index: 1;
}

/* 强制覆盖所有可能的智能提示相关元素 */
:deep(.monaco-editor .suggest-widget.visible) {
  z-index: 9999999 !important;
  position: fixed !important;
}

:deep(.monaco-editor .suggest-widget .monaco-list) {
  background: transparent !important;
}

:deep(.monaco-editor .suggest-widget .suggest-status-bar) {
  background: rgba(0, 0, 0, 0.8) !important;
  border-top: 1px solid rgba(164, 244, 186, 0.3) !important;
}

/* 覆盖全局容器样式 */
.command-editor {
  position: relative;
  z-index: 10 !important;
}

.monaco-container {
  position: relative;
  z-index: 10 !important;
}

/* 帮助对话框 */
.pattern-help ul {
  list-style: none;
  padding: 0;
}

.pattern-help li {
  margin-bottom: 10px;
  padding: 12px;
  background: rgba(164, 244, 186, 0.1);
  border: 1px solid rgba(164, 244, 186, 0.2);
  border-radius: 8px;
  transition: all 0.3s ease;

  &:hover {
    background: rgba(164, 244, 186, 0.15);
    border-color: rgba(164, 244, 186, 0.3);
  }
}

.pattern-help code {
  background: rgba(164, 244, 186, 0.2);
  padding: 4px 8px;
  border-radius: 4px;
  color: #00eaff;
  font-family: 'Courier New', monospace;
  text-shadow: 0 0 5px rgba(0, 234, 255, 0.2);
}

.module-help h4 {
  color: #00eaff;
  margin-bottom: 15px;
  text-shadow: 0 0 10px rgba(0, 234, 255, 0.3);
}

.module-help h5 {
  color: rgba(255, 255, 255, 0.8);
  margin: 20px 0 10px 0;
}

.module-parameters {
  margin-top: 20px;
}

.no-module-selected {
  text-align: center;
  padding: 40px;
  color: rgba(255, 255, 255, 0.6);
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .header-content {
    flex-direction: column;
    gap: 20px;
    align-items: stretch;
  }

  .page-title {
    font-size: 2em;
  }
}

@media (max-width: 768px) {
  .adhoc-content {
    padding: 15px;
  }

  .page-header {
    padding: 20px;
  }

  .execution-form-section,
  .terminal-section {
    padding: 20px;
  }

  .section-header {
    flex-direction: column;
    gap: 15px;
    align-items: stretch;
  }

  .terminal-header {
    flex-direction: column;
    gap: 10px;
    align-items: stretch;
  }

  .header-actions {
    flex-wrap: wrap;
    justify-content: center;
  }

  .terminal-container {
    height: 300px;
  }

  .monaco-container {
    height: 50px;
  }

  .page-title {
    font-size: 1.8em;
    text-align: center;
  }

  .page-subtitle {
    text-align: center;
  }
}

@media (max-width: 480px) {
  .glass-action-btn {
    min-width: 70px !important;
    padding: 6px 8px !important;
    font-size: 11px !important;

    i {
      font-size: 11px !important;
    }

    span {
      font-size: 11px !important;
    }
  }

  .terminal-container {
    height: 250px;
    padding: 15px;
  }

  .monaco-container {
    height: 40px;
  }
}

/* 统一按钮样式 */
.glass-button {
  background: rgba(164, 244, 186, 0.15) !important;
  border: 1px solid rgba(164, 244, 186, 0.3) !important;
  color: rgba(255, 255, 255, 0.9) !important;
  transition: all 0.3s ease !important;
  backdrop-filter: blur(10px) !important;
  border-radius: 8px !important;
  font-weight: 500 !important;

  &:hover {
    background: rgba(164, 244, 186, 0.25) !important;
    border-color: rgba(164, 244, 186, 0.5) !important;
    color: #ffffff !important;
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(164, 244, 186, 0.3);
  }

  &:active {
    transform: translateY(0);
  }

  &.primary {
    background: rgba(164, 244, 186, 0.2) !important;
    border-color: rgba(164, 244, 186, 0.4) !important;

    &:hover {
      background: rgba(164, 244, 186, 0.3) !important;
      border-color: rgba(164, 244, 186, 0.6) !important;
    }
  }

  &.danger {
    background: rgba(255, 107, 107, 0.15) !important;
    border-color: rgba(255, 107, 107, 0.3) !important;

    &:hover {
      background: rgba(255, 107, 107, 0.25) !important;
      border-color: rgba(255, 107, 107, 0.5) !important;
      box-shadow: 0 4px 12px rgba(255, 107, 107, 0.3);
    }
  }

  &.validate-button {
    background: rgba(135, 206, 235, 0.15) !important;
    border-color: rgba(135, 206, 235, 0.3) !important;

    &:hover {
      background: rgba(135, 206, 235, 0.25) !important;
      border-color: rgba(135, 206, 235, 0.5) !important;
      box-shadow: 0 4px 12px rgba(135, 206, 235, 0.3);
    }
  }

  &.clear-button {
    background: rgba(255, 193, 7, 0.15) !important;
    border-color: rgba(255, 193, 7, 0.3) !important;

    &:hover {
      background: rgba(255, 193, 7, 0.25) !important;
      border-color: rgba(255, 193, 7, 0.5) !important;
      box-shadow: 0 4px 12px rgba(255, 193, 7, 0.3);
    }
  }

  &:disabled {
    opacity: 0.5 !important;
    cursor: not-allowed !important;
    transform: none !important;
    box-shadow: none !important;
  }
}

/* 凭据选择样式 */
.credential-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.credential-name {
  flex: 1;
  margin-right: 10px;
  color: rgba(255, 255, 255, 0.9);
}

.credential-type-tag {
  flex-shrink: 0;
}

@media (max-width: 768px) {
  .execution-form-section {
    padding: 15px;
  }

  .section-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 15px;
  }

  .header-actions {
    width: 100%;
    justify-content: flex-start;
  }

  .monaco-container {
    height: 200px;
  }

  .terminal-container {
    height: 250px;
  }

  .inventory-selection {
    flex-direction: column;
    align-items: flex-start;
    gap: 15px;
  }
}

/* 工具栏按钮样式 - 与inventory页面保持一致 */
.glass-button {
  background: rgba(164, 244, 186, 0.15) !important;
  border: 1px solid rgba(164, 244, 186, 0.3) !important;
  color: rgba(255, 255, 255, 0.9) !important;
  transition: all 0.3s ease !important;
  backdrop-filter: blur(10px) !important;
  border-radius: 8px !important;
  padding: 8px 16px !important;
  font-size: 14px !important;
  font-weight: 500 !important;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1) !important;

  &:hover {
    background: rgba(164, 244, 186, 0.25) !important;
    border-color: rgba(164, 244, 186, 0.5) !important;
    color: #ffffff !important;
    transform: translateY(-2px) !important;
    box-shadow: 0 4px 16px rgba(164, 244, 186, 0.2) !important;
  }

  i {
    margin-right: 6px !important;
    color: #00eaff !important;
  }

  /* 执行按钮 - 绿色 */
  &.execute-button {
    background: rgba(34, 197, 94, 0.2) !important;
    border-color: rgba(34, 197, 94, 0.4) !important;
    color: #ffffff !important;

    &:hover {
      background: rgba(34, 197, 94, 0.3) !important;
      border-color: rgba(34, 197, 94, 0.6) !important;
      box-shadow: 0 4px 16px rgba(34, 197, 94, 0.3) !important;
    }

    i {
      color: #22c55e !important;
    }
  }

  /* 取消按钮 - 红色 */
  &.cancel-button {
    background: rgba(239, 68, 68, 0.2) !important;
    border-color: rgba(239, 68, 68, 0.4) !important;
    color: #ffffff !important;

    &:hover {
      background: rgba(239, 68, 68, 0.3) !important;
      border-color: rgba(239, 68, 68, 0.6) !important;
      box-shadow: 0 4px 16px rgba(239, 68, 68, 0.3) !important;
    }

    i {
      color: #ef4444 !important;
    }
  }

  /* 验证按钮 - 蓝色 */
  &.validate-button {
    background: rgba(59, 130, 246, 0.2) !important;
    border-color: rgba(59, 130, 246, 0.4) !important;
    color: #ffffff !important;

    &:hover {
      background: rgba(59, 130, 246, 0.3) !important;
      border-color: rgba(59, 130, 246, 0.6) !important;
      box-shadow: 0 4px 16px rgba(59, 130, 246, 0.3) !important;
    }

    i {
      color: #3b82f6 !important;
    }
  }
}

/* 操作按钮样式 - 统一使用inventory页面样式 */
.action-glass-button {
  background: rgba(164, 244, 186, 0.1) !important;
  border: 1px solid rgba(164, 244, 186, 0.3) !important;
  color: rgba(255, 255, 255, 0.9) !important;
  backdrop-filter: blur(10px) !important;
  border-radius: 6px !important;
  padding: 6px 12px !important;
  font-size: 12px !important;
  transition: all 0.3s ease !important;

  &:hover {
    background: rgba(164, 244, 186, 0.2) !important;
    border-color: rgba(164, 244, 186, 0.5) !important;
    color: rgba(255, 255, 255, 1) !important;
    transform: translateY(-1px) !important;
    box-shadow: 0 4px 12px rgba(164, 244, 186, 0.3) !important;
  }

  &:active {
    transform: translateY(0) !important;
    box-shadow: 0 2px 6px rgba(164, 244, 186, 0.2) !important;
  }

  /* 清空按钮 - 红色 */
  &.clear-action {
    border-color: rgba(239, 68, 68, 0.3) !important;

    &:hover {
      background: rgba(239, 68, 68, 0.2) !important;
      border-color: rgba(239, 68, 68, 0.5) !important;
      box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3) !important;
    }
  }

  /* 滚动按钮 - 蓝色 */
  &.scroll-action {
    border-color: rgba(59, 130, 246, 0.3) !important;

    &:hover {
      background: rgba(59, 130, 246, 0.2) !important;
      border-color: rgba(59, 130, 246, 0.5) !important;
      box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3) !important;
    }
  }
}

/* Monaco编辑器智能提示样式 */
:deep(.monaco-editor) {
  /* 智能提示弹窗样式 */
  .suggest-widget {
    background: rgba(30, 30, 30, 0.95) !important;
    border: 1px solid rgba(164, 244, 186, 0.3) !important;
    border-radius: 8px !important;
    backdrop-filter: blur(10px) !important;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3) !important;
    z-index: 1000 !important;
    max-height: 180px !important;
  }

  .suggest-widget .monaco-list .monaco-list-row {
    background: transparent !important;
    border-radius: 4px !important;
    margin: 2px 4px !important;

    &:hover {
      background: rgba(164, 244, 186, 0.1) !important;
    }

    &.focused {
      background: rgba(164, 244, 186, 0.2) !important;
    }
  }

  .suggest-widget .monaco-list .monaco-list-row .suggest-icon {
    color: #4FC1FF !important;
  }

  .suggest-widget .monaco-list .monaco-list-row .monaco-highlighted-label {
    color: #A4F4BA !important;

    .highlight {
      background: transparent !important;
      color: #00D7FF !important;
      font-weight: bold !important;
    }
  }

  .suggest-widget .monaco-list .monaco-list-row .codicon {
    color: #4FC1FF !important;
  }

  .suggest-widget .monaco-list .monaco-list-row .suggest-label {
    color: #A4F4BA !important;
    background: transparent !important;
  }

  .suggest-widget .monaco-list .monaco-list-row .suggest-label .monaco-highlighted-label .highlight {
    background: transparent !important;
    color: #00D7FF !important;
    font-weight: bold !important;
    text-decoration: none !important;
    border: none !important;
    box-shadow: none !important;
  }

  .suggest-widget .monaco-list .monaco-list-row .suggest-detail {
    color: #87CEEB !important;
    font-size: 12px !important;
  }

  .suggest-widget .monaco-list .monaco-list-row .suggest-documentation {
    color: #D4D4D4 !important;
    background: rgba(164, 244, 186, 0.05) !important;
    border-radius: 4px !important;
    padding: 4px 8px !important;
    margin-top: 4px !important;
  }

}

/* 智能提示样式 - 只在有内容时显示 */
:deep(.monaco-editor .suggest-widget) {
  background: rgba(0, 0, 0, 0.9) !important;
  border: 1px solid rgba(164, 244, 186, 0.5) !important;
  border-radius: 8px !important;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.8) !important;
  z-index: 9999 !important;
  position: absolute !important;
}

/* 智能提示内容样式 */
/* 智能提示内容样式 - 已移至底部统一处理 */

/* 确保Monaco编辑器容器允许溢出 */
.monaco-editor-container {
  overflow: visible !important;
}

.command-editor .monaco-editor-container {
  overflow: visible !important;
}

/* 基础智能提示样式 */
:deep(.monaco-editor .suggest-widget .monaco-list .monaco-list-row) {
  color: #ffffff !important;
  background: transparent !important;
}

:deep(.monaco-editor .suggest-widget .monaco-list .monaco-list-row:hover) {
  background: rgba(164, 244, 186, 0.2) !important;
}

:deep(.monaco-editor .suggest-widget .monaco-list .monaco-list-row.focused) {
  background: rgba(0, 234, 255, 0.3) !important;
}

:deep(.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-label) {
  color: #ffffff !important;
}

:deep(.monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon) {
  color: #00eaff !important;
}
</style>


